/**
 * Copyright 2014 the original author or authors. All rights reserved.
 */
package com.visionet.security.realm;

import javax.annotation.Resource;

import com.visionet.security.domain.dto.UserDTO;
import com.visionet.security.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import com.visionet.security.domain.entity.User;
import com.visionet.security.support.AuthorizationConverter;
import com.visionet.security.base.enums.UserStatus;
import com.visionet.security.utils.CodecUtils;

/**
 * 自定义 DB Realm
 *
 * @author suxiaojing
 * @date
 * @since 0.0.1
 */
public class DBRealm extends AuthorizingRealm {

	@Resource
	private UserService userService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
		UserDTO securityUser = (UserDTO) principal.getPrimaryPrincipal();
		User user = userService.findOne(securityUser.getId());
		return AuthorizationConverter.getAuthorizationInfo(user);
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		if (StringUtils.isEmpty(token.getUsername())) {
			throw new AccountException("The Username are not allowed.");
		}
		User user = userService.findByLoginName(token.getUsername());
		if (user == null) {
			throw new UnknownAccountException(String.format("No account found for user [%s]",
					token.getUsername()));
		}
		if (StringUtils.equals(UserStatus.LOCKED.toString(), user.getStatus().toString())) {
			throw new AccountException("The Username had leaved.");
		}
		
		byte[] salt = CodecUtils.decodeStringHex(user.getSalt());
		UserDTO userTransfer = new UserDTO();
		userTransfer.setId(user.getId());
		userTransfer.setName(user.getName());
		userTransfer.setLoginName(user.getLoginName());
		return new SimpleAuthenticationInfo(userTransfer, user.getPassword(), ByteSource.Util.bytes(salt), getName());
	}
}
